

/** 游戏加载模块 */

import { BundleManager_blxf } from "../Manager/BundleManager";
import { CsvManager_blxf } from "../Manager/CsvManager";
import { UtilsModule_blxf } from "./UtilsModule";

let uuids = {};

const {ccclass, property} = cc._decorator;

@ccclass
export class LoadModule_blxf {

    private constructor() { }

    private static _LoadModule_blxf: LoadModule_blxf = new LoadModule_blxf();

    public static get instance() {
        return this._LoadModule_blxf;
    }

    private _gameFonts: any = {};

    /**
     * 通过名字加载预制体
     * @param names 预制体数组
     * @param pregressCallback 加载进度
     * @param completeCallback 加载完成回调
     */
    LoadPrefab_blxf ( names: string[], pregressCallback: object, completeCallback: object ){
        let urls: string[] = [];

        names.forEach( pfName => {
            let _pfPath: string = CsvManager_blxf.instance.getPrefabPath_blxf( pfName );
            _pfPath && urls.push( _pfPath );
        });
        this.LoadPrefabByUrls_blxf(urls, pregressCallback, completeCallback);
    };

    /**
     * 通过路径加载预制体
     * @param names 预制体数组
     * @param pregressCallback 加载进度
     * @param completeCallback 加载完成回调
     */
    LoadPrefabByUrls_blxf (urls: string[], pregressCallback: object, completeCallback: any) {
        let _bundle = BundleManager_blxf.instance.Bundle_Prefab;
        // cc.log('bundle ==', bundle);
        _bundle.load(urls, pregressCallback, (err, assets) => {
            if ( err ) return UtilsModule_blxf.instance.Log_blxf(`加载资源组失败：${urls}, error:${err}`, 3);

            assets.forEach((item, index) => {
                // resources[urls[index]] = item;
                uuids[urls[index]] = item._uuid;
                item.addRef && item.addRef();
            })

            completeCallback( assets );
        })
    };

    /**
     * 获取预制体节点
     * @param name 预制体名字
     * @returns 返回节点
     */
    getInstantiate_blxf ( name: string, isCheck: boolean = false ) {
        let _pfPath: string = CsvManager_blxf.instance.getPrefabPath_blxf( name );
        let _uuid = uuids[ _pfPath ];
        if (!_uuid) return !isCheck && cc.error(`${_pfPath}资源还未加载`, name);
        if (!this.getAsset_blxf(_uuid)) return;
        return cc.instantiate(this.getAsset_blxf(_uuid));
    }

    getAsset_blxf (_uuid) {
        let asset = cc.assetManager.assets['_map'][_uuid];
        // cc.log('asset =>', asset);
        return asset;
    }

    /**
     * 
     * @param options prefabNode, parentNode, position = cc.v2(0, 0), zIndex = 0, options
     * @returns 
     */
    LoadNode_blxf (  options: object ) {
        let _prefabNode = options['prefabNode'];
        let _parentNode = options['parentNode']  || cc.find('Canvas/game_panel');
        if ( !_prefabNode || !cc.isValid(_prefabNode) ) return;
        if ( !_parentNode || !cc.isValid(_parentNode) ) return;
        let newNode: cc.Node = cc.instantiate(_prefabNode);
        if ( !newNode ) return;
        let _zIndex = options['zIndex'] || 0;
        let _position = options['position'] || cc.v2(0, 0);

        newNode.zIndex = _zIndex;
        newNode.position = _position;
        _parentNode.addChild(newNode);

        return newNode;
    };

    
    /**
     * 加载图片
     * @param options 图集路径path: string, 图片名imgName: string, 图片imgSpr: cc.Sprite, 回调函数cb: any, 图片适配盒子imgBox: cc.Node = null
     * isSpecial: 是否最大不超过原尺寸
     */
    LoadImg_blxf ( options: object = {} ) {
        let _path: string, _imgName: string;
        let _cb: any, _imgSpr: cc.Sprite, _imgBox: cc.Node, _isSpecial: boolean, _isImg: boolean;

        _path = options['path'], _imgName = options['imgName'];
        _isImg = options['isImg'];
        if ( !_path || !_imgName && !_isImg ) {
            return UtilsModule_blxf.instance.Log_blxf(`xtf_LoadImg 参数错误 >> _path=${_path}, _imgName=${_imgName}`, 2);
        }

        _cb = options['cb'], _isSpecial = options['isSpecial'];
        _imgSpr = options['imgSpr'], _imgBox = options['imgBox'];

        let _bundle = BundleManager_blxf.instance.Bundle_Image;
        let _type: any = _isImg ? cc.SpriteFrame : cc.SpriteAtlas;
        _bundle.load(_path, _type, (err, atlas) => {
            if ( err ) {
                return UtilsModule_blxf.instance.Log_blxf(`图集：${_path}中图片：${_imgName}加载失败！！！`, 2);
            }

            try {
                let _spriteFrame = _isImg ? atlas : atlas.getSpriteFrame(_imgName);
                _cb && _cb(_spriteFrame, atlas);

                if ( _imgSpr ) {
                    _imgSpr.spriteFrame = _spriteFrame;
                }

                // cc.log('imgName =', path, imgName, atlas.getSpriteFrame(imgName));
                _imgBox && UtilsModule_blxf.instance.setSpriteSizeInNodes_blxf( _imgSpr, _imgBox, _isSpecial );

                _imgSpr.addAutoReleaseAsset(atlas);
                _imgSpr.addAutoReleaseAsset(_spriteFrame);
            } catch (e) {

            }
        });
    };

    // 加载网络图片 [一般用于头像和友情链接]
    loadNetworkImage ( url: string, sprite: cc.Sprite ) {
        cc.assetManager.loadRemote(url, (err, texture) => {
            if (!!err) return;
            // sprite.spriteFrame = new cc.SpriteFrame(texture);
        });
    }

    /**
     * 加载文本字体
     * @param text 文本组件
     * @param fileName 字体文件名
     */
    LoadFont_blxf ( text: cc.Label, fileName: string ) {
        if ( this._gameFonts[ fileName ] ) {
            return this.SetFont_blxf(text, fileName);
        }

        let _bundle = BundleManager_blxf.instance.Bundle_Font;
        if ( !_bundle ) return;

        _bundle.load(fileName, cc.Font, ( err: any, font: cc.Font ) => {
            if ( err ) {
                return UtilsModule_blxf.instance.Log_blxf(`loadFont_blxf error`, 3);
            }

            this._gameFonts[ fileName ] = font;

            this.SetFont_blxf(text, fileName);
        });
    }
   
    /**
     * 设置字体
     * @param text 文本组件
     */
    SetFont_blxf ( text: cc.Label, fileName: string ) {
        text.font = this._gameFonts[fileName];
    }

    /**
     * 加载Spine动画
     * @param spinePath 动画路径
     * @param skeleton 动画
     * @param cb 加载完成回调
     */
    LoadSpine_blxf ( bundName:string, spinePath: string, skeleton: sp.Skeleton, cb: any ) {
        let _bundle = BundleManager_blxf.instance[ `Bundle_${bundName}` ];
        if ( !_bundle ) return UtilsModule_blxf.instance.Log_blxf('Spine分包未加载', 2);

        _bundle.load( spinePath, sp.SkeletonData, ( err: any, skeletonData: sp.SkeletonData ) => {
            if ( err ) return cc.error(err);
            try {
                if (skeleton) {
                    if ( skeleton.skeletonData ) {
                        this.onReleaseAssets_blxf([ skeleton.skeletonData ]);
                    }
                    skeleton.skeletonData = skeletonData;
                    skeleton.addAutoReleaseAsset(skeletonData);
                } else {
                    skeletonData.addRef && skeletonData.addRef();
                }
                cb && cb( skeletonData );
            } catch (e) {
                // cc.error('loadSpineRes error: ', e.stack);
            }
        })
    }

    // 释放资源
    onReleaseAssets_blxf ( assets: any ) {
        if ( !assets ) return;
        assets.forEach( asset => {
            if ( !asset ) return;
            // cc.log('decRef ==>', asset._name, asset._ref, asset._uuid);
            asset.decRef && asset.decRef();
            if (asset._ref == 0) asset = null;
        })
    }

}
